﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.IO;
using log4net;

namespace DSServer.Banking
{
    class AccountI : AccountDisp_
    {
        private static readonly ILog log = log4net.LogManager.GetLogger(typeof(AccountI));
        private double balance;
        private string PESEL;
        private string password;
        private bool logged = false;
        private readonly string directory = "BankAccounts";
        private string token;

        public override string login(string PESEL, string password, Ice.Current current__)
        {
            if (logged)
                throw new UserAlreadyLoggedException();

            this.PESEL = PESEL;
            this.password = password;
            try
            {
                string[] lines = File.ReadAllLines(directory + "/" + PESEL);
                if (lines.Length != 2 || lines[0] != password)
                    throw new InvalidPeselOrPasswordException();

                balance = double.Parse(lines[1]);
            }
            catch (FileNotFoundException e) {
                throw new InvalidPeselOrPasswordException();
            }
            catch (Exception e)
            {
                log.Error(e);
                throw;
            }
            logged = true;

            return this.token = Guid.NewGuid().ToString();
        }

        public override void withdraw(string token, double amount, Ice.Current current__)
        {
            CheckPermitions(token);
            if (balance < amount)
                throw new InsufficientFoundsException();
            balance -= amount;
            Persist();
        }

        public override void deposit(string token, double amount, Ice.Current current__)
        {
            CheckPermitions(token);
            balance += amount;
            Persist();
        }

        public override double getBalance(string token, Ice.Current current__)
        {
            CheckPermitions(token);
            return balance;
        }

        public override void logout(string token, Ice.Current current__)
        {
            CheckPermitions(token);
            Persist();
            logged = false;
        }

        private void Persist()
        {
            try
            {
                File.WriteAllLines(directory + "/" + PESEL, new string[] { password, balance.ToString() });
            }
            catch (IOException e)
            {
                log.Error(e);
            }
        }

        private void CheckPermitions(string token)
        {
            if (!logged)
                throw new UserNotLoggedException();
            if (token != this.token)
                throw new UnauthorizedAccessException();
        }

        internal void InternalLogout()
        {
            logged = false;
        }
    }
}
